/*
 * 部分参考RT-Thread
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
*/
#ifndef __LIST_H__
#define __LIST_H__
 
#include "type.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 通过链表节点返回包含这个链表节点的结构类型地址
 * @param 链表节点地址
 * @param 需要获取地址的结构类型
 * @param 链表节点在结构类型中的成员位置
 */
#define etf_container_of(ptr, type, member)         ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

/**
 * @brief 初始化一个链表
 *
 * @param 链表地址
 */
etf_inline void etf_list_init(etf_list_t *l){
    l->next = l->prev = l;
}

/**
 * @brief 在当前节点后面插入链表
 *
 * @param 当前节点地址
 * @param 需要插入的节点地址
 */
etf_inline void etf_list_insert_after(etf_list_t *l, etf_list_t *n){
    l->next->prev = n;
    n->next = l->next;

    l->next = n;
    n->prev = l;
}

/**
 * @brief 在当前节点前插入链表
 *
 * @param 当前节点地址
 * @param 需要插入的节点地址
 */
etf_inline void etf_list_insert_before(etf_list_t *l, etf_list_t *n){
    l->prev->next = n;
    n->prev = l->prev;

    l->prev = n;
    n->next = l;
}

/**
 * @brief 移除节点
 * @param 需要移除的节点
 */
etf_inline void etf_list_remove(etf_list_t *n){
    n->next->prev = n->prev;
    n->prev->next = n->next;

    n->next = n->prev = n;
}

/**
 * @brief 检查列表是否为空
 * @param 列表地址
 */
etf_inline int etf_list_isempty(const etf_list_t *l){
    return l->next == l;
}

/**
 * @brief 获取列表长度
 * @param 列表地址
 */
etf_inline unsigned int etf_list_len(const etf_list_t *l){
    unsigned int len = 0;
    const etf_list_t *p = l;
    while (p->next != l)
    {
        p = p->next;
        len ++;
    }

    return len;
}

/**
 * @brief 通过节点获取当前结构地址
 * @param 链表节点地址
 * @param 需要获取地址的结构类型
 * @param 链表节点在结构类型中的成员位置
 */
#define etf_list_entry(node, type, member)          etf_container_of(node, type, member)

 
#ifdef __cplusplus
}
#endif
 
#endif
 

